﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Resources;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace Jok.Client.Loader.PackagesService
{
    public partial class Package
    {
        public Uri Location { get; set; }
        public bool DownloadRequired { get; set; }
        public string FullName
        {
            get { return String.Concat(this.Name, "(", this.Version, ").dll"); }
        }


        public static string GetVersion(Stream packageStream)
        {
            StreamResourceInfo manifestStreamInfo = Application.GetResourceStream(
                new StreamResourceInfo(packageStream, null),
                new Uri("Version.xml", UriKind.Relative));

            using (XmlReader reader = XmlReader.Create(manifestStreamInfo.Stream))
            {
                if (reader.ReadToFollowing("Version"))
                    return reader.GetAttribute("ID");

                return String.Empty;
            }
        }
        public static IEnumerable<Assembly> LoadPackagedAssemblies(Stream packageStream)
        {
            List<Assembly> assemblies = new List<Assembly>();
            StreamResourceInfo packageStreamInfo = new StreamResourceInfo(packageStream, "application/binary");

            IEnumerable<AssemblyPart> parts = GetDeploymentParts(packageStreamInfo);

            foreach (AssemblyPart ap in parts)
            {
                StreamResourceInfo sri = Application.GetResourceStream(packageStreamInfo, new Uri(ap.Source, UriKind.Relative));

                //TODO: This has not been tested with SL3 Transparent parts and
                // will likely cause a failure because they aren't actually
                // packed in the package as a stream. 
                assemblies.Add(ap.Load(sri.Stream));
            }
            return assemblies;
        }
        private static IEnumerable<AssemblyPart> GetDeploymentParts(StreamResourceInfo xapStreamInfo)
        {
            Uri manifestUri = new Uri("AppManifest.xaml", UriKind.Relative);
            StreamResourceInfo manifestStreamInfo = Application.GetResourceStream(xapStreamInfo, manifestUri);
            Stream manifestStream = manifestStreamInfo.Stream;
            List<AssemblyPart> assemblyParts = new List<AssemblyPart>();
            using (XmlReader reader = XmlReader.Create(manifestStream))
            {
                if (reader.ReadToFollowing("AssemblyPart"))
                {
                    do
                    {
                        string source = reader.GetAttribute("Source");

                        if (source != null)
                        {
                            assemblyParts.Add(new AssemblyPart() { Source = source });
                        }
                    }
                    while (reader.ReadToNextSibling("AssemblyPart"));
                }
            }

            return assemblyParts;
        }
    }
}
